<?php
/**
 * Created by PhpStorm.
 * User: zhongbaitong
 * Date: 2020/1/15
 * Time: 14:14
 */

namespace app\im\home;

use think\swoole\Server;

class WebSocket extends Server
{
    protected $host = '0.0.0.0'; //监听所有地址
    protected $port = 9501; //监听9501端口

    protected $mode = SWOOLE_PROCESS;
    protected $sockType = SWOOLE_SOCK_TCP | SWOOLE_SSL;

    protected $serverType = 'socket';
    protected $option = [
        'worker_num'=> 4, //设置启动的Worker进程数
        'daemonize'	=> false, //守护进程化（上线改为true）
        'backlog'	=> 128, //Listen队列长度
        'dispatch_mode' => 2, //固定模式，保证同一个连接发来的数据只会被同一个worker处理

        //心跳检测：每60秒遍历所有连接，强制关闭10分钟内没有向服务器发送任何数据的连接
        'heartbeat_check_interval' => 60,
        'heartbeat_idle_time' => 600,

        // 开启支持 ssl
        'ssl_cert_file' => "/etc/nginx/ssl_key/3046427_ik.kder.top.pem",
        'ssl_key_file'  => "/etc/nginx/ssl_key/3046427_ik.kder.top.key"
    ];

    //建立连接时回调函数
    public function onOpen($server,$req)
    {
        //客户端标识
        $fd = $req->fd;
        $data = [
            "type" => "init"
        ];
        $server->push($fd, json_encode($data));

        echo "标识{$fd}建立了连接\n";
    }

    //接收数据时回调函数
    public function onMessage($server,$frame)
    {
        $fd = $frame->fd;
        $message = json_decode($frame->data,1);

        echo "来自标识" . $fd . "的消息";
        var_dump($message);
        if(isset($message["type"])){
            switch ($message["type"]){
                case "init":
                    $user_id = $this->getUserId($message["token"]);
                    cache("socket:user:".$user_id,$fd);
                    $mess = "user:" . $user_id . " -> fd:" . cache("socket:user:".$user_id) . PHP_EOL;
                    $data = [
                        "type" => "init_result",
                        "mess" => $mess
                    ];
                    $server->push($fd, json_encode($data));
                    break;
                case "newMess":
                    $obj_uid = $this->getUserId($message["obj_token"]);

                    $fd = cache("socket:user:".$obj_uid);
                    if($server->exist($fd)){
                        $server->push($fd, json_encode($message));
                    }
                    break;
                case "closeConnect":
                    // 清除关联，即删除 cache
                    break;
                default:
                    echo "待处理 type  " . $message['type'];
                    break;
            }
        }
    }

    //连接关闭时回调函数
    public function onClose($server,$fd)
    {
        echo "标识{$fd}关闭了连接\n";
    }

    public function getUserId($token){
        $str = str_decrypt($token, md5(config('wechat.token_yan')));
        $arr = explode('/', $str);
        return $arr[0];
    }
}